package com.linkgie.galaxyframework.kvstorage;

/**
 * 键值存储；
 * <p>
 * 
 * {@link KVStorage} 定义了一种以“键空间（keyspace”提供一种树状层次化地对键值数据进行分类/分区管理的存储模型，<br>
 * 键（key）只需要在某一个特定的键空间（keyspace）中保持唯一， <br>
 * 键空间（keyspace）和键（key）通过键空间分隔符（keyspace seperator）连接组成了实际存储的唯一键。。
 * <p>
 * 
 * 键空间（keyspace）由一段字符串形式的键路径（keypath）表示， <br>
 * 键路径（path）由一组字符以“键路径分隔符（keypath seperator）”连接组成， <br>
 * 其中的每一个元素称为“ 键路径名称（keypath name）”；
 * <p>
 * 
 * 示例：
 * <p>
 * 
 * 假设“键空间分隔符”为字符 '@'， “键路径分隔符”为字符 '/' ，<br>
 * 
 * 'business/user/detail@' 构成了一个 keyspace，其中 'business/user/detail' 是 keypath
 * ，<br>
 * 
 * keypath 是一组路径名（path names） ['business', 'user', 'detail'] 通过键路径分隔符'/'连接而成；
 * <p>
 * 
 * {@link KVStorage} 接口被有意设计为只能向下访问子级键空间（通过方法
 * {@link #getStorage(String...)}）而不能向上访问上级键空间，目的是为了实现基于键空间的数据访问隔离；
 * <p>
 * 
 * 如果需要同时访问子级键空间及其父级键空间，应当由业务逻辑实现者自行显式地传递所需的父级键空间存储对象；
 * 
 * 
 * @author spring
 *
 */
public interface KVStorage {

	public static final String DEFAULT_STRING_ENCODING = "UTF-8";

	/**
	 * 存储上下文；
	 * 
	 * @return
	 */
	KVStorageContext getContext();

	/**
	 * 键空间；
	 * 
	 * <p>
	 * 
	 * 键空间总是以键路径分隔符开始，中间连接 0 或多个键路径名；
	 * <p>
	 * 
	 * 根存储的键空间为键路径分隔符 {@link KVStorageSettings#getKeypathSeperator()};
	 * 
	 * @return 键空间的字符值，不包含键空间分隔符；
	 */
	String getKeyspace();

	/**
	 * 名称；
	 * <p>
	 * 即键空间的最后一项键路径名称（keypath name）；
	 * 
	 * <p>
	 * 根
	 * 
	 * @return
	 */
	String getName();

	/**
	 * 获得指定的子级键空间的存储对象；
	 * 
	 * @param keypathNames 子级键空间的路径名称列表；
	 * @return
	 */
	KVStorage getStorage(String... keypathNames);

	/**
	 * 返回原始的键值数据图；
	 * 
	 * @return
	 */
	KVMap<byte[]> getOriginMap();

	/**
	 * 返回能够自动将值转为基本类型的键值数据图；
	 * <p>
	 * 
	 * @return
	 */
	PrimitiveKVMap getPrimitiveMap();

	/**
	 * 返回能够自动将值转为指定类型的键值数据图；
	 * 
	 * @param <T>
	 * @param valueType
	 * @return
	 */
	<T> KVMap<T> getTypeMap(Class<T> valueType);

	default KVMap<String> getStringMap() {
		return getTypeMap(String.class);
	}

}
